#!/usr/bin/env python3

import click
import numpy as np
import qiadj as adj
import pandas as pd
from pandas.tseries.offsets import MonthEnd
from qidat import *
from qiplot import *
from qiutil import *
import portfolio

# 避免使用科学计数法
pd.options.display.float_format = '{:20,.4f}'.format

@click.group()
def prepdata():
    pass

@click.group()
def analyze():
    pass

@prepdata.command()
@click.option('--src-path', default=DEFAULT_DATA_PATH, help='source data location')
@click.option('--data-file', default=DEFAULT_SILVER_FILE, help='full path of silver data file')
def gen_ttm_data(src_path, data_file):
    do_gen_ttm_data(src_path, data_file)

def do_gen_ttm_data(src_path=DEFAULT_DATA_PATH, data_file=DEFAULT_SILVER_FILE):
    raw = load_raw_from_files(src_path)
    ttm = create_ttm_from_raw(raw)
    save_raw_and_ttm(raw, ttm, data_file)

@analyze.command()
@click.option('--stock', required=True, help='stock code')
@click.option('--date', required=True, help='specific date')
def show_stock_info(stock, date):
    do_stock_info(stock, date)

def do_stock_info(stock, date, data_file=DEFAULT_SILVER_FILE):
    print(f"Get stock information of {stock} on {date}")
    (raw, ttm) = load_raw_and_ttm(data_file)
    data = raw.mv_data[(raw.mv_data.STOCK_CODE == stock) &
                       (raw.mv_data.TRADE_DATE <= date) &
                       (raw.mv_data.TRADE_DATE2 > date)]
    data2 = raw.equity_data[(raw.equity_data.STOCK_CODE == stock) &
                           (raw.equity_data.E_RPT_PERIOD <= date) &
                           (raw.equity_data.E_RPT_PERIOD2 > date) ]
    data3 = raw.sw_ind[(raw.sw_ind.STOCK_CODE == stock) &
                       (raw.sw_ind.ENTRY_DATE <= date) &
                       (raw.sw_ind.REMOVE_DATE > date) ]
    tmp = pd.merge(data, data2, on=["STOCK_CODE"])
    tmp = pd.merge(tmp, data3, on=["STOCK_CODE"])
    str_out = tmp.to_csv(None)
    print(str_out)

@prepdata.command()
@click.option('--date', required=True, help='specific date')
@click.option('--data-file', default=DEFAULT_SILVER_FILE,
              help='instead of print to std, save the result to file')
@click.option('--report-file', default="",
              help='instead of print to std, save the result to file')
def show_section_info(date, data_file, report_file):
    single_section_info(date, data_file, report_file)

def single_section_info(date, data_file=DEFAULT_SILVER_FILE, report_file=""):
    print(f"Get cross-section information of stocks on {date}")
    (raw, ttm) = load_raw_and_ttm(data_file)
    mdata = adj.calc_section_data(date, raw, ttm)

    if(report_file == ""):
        print(mdata.to_string())
    elif(report_file.endswith(".xlsx")):
        mdata.to_xls(report_file)
    else:
        # use hdf5 as default
        mdata.to_hdf(report_file, f"DT{date}", mode='a')

@prepdata.command()
def plot_sizef():
    (raw, ttm) = load_raw_and_ttm(DEFAULT_SILVER_FILE)
    sizef_plot(raw)

@prepdata.command()
@click.option('--start', default=DEFAULT_START_DATE, help='start date')
@click.option('--end', default=DEFAULT_END_DATE, help="end date")
@click.option('--src-data-file', default=DEFAULT_SILVER_FILE,
              help="source data file to produce gold data")
@click.option('--store-file', default=DEFAULT_GOLD_FILE,
              help="file to store section data")
def gen_adjstaging_data(start, end, src_data_file, store_file):
    (raw, ttm) = load_raw_and_ttm(src_data_file)
    gd = adj.create_adj_staging(raw, ttm, start, end)
    adj.save_adjstaging_to_h5file(gd, store_file)

@analyze.command()
@click.option('--data-file', default=DEFAULT_GOLD_FILE,
              help='data file for gold level data')
def gen_adjroe_corrs_data(data_file):
    gd = adj.load_adjstaging_from_h5file(data_file)
    adj.calc_adj_roes(gd)
    corrs = pd.Series(adj.gen_corr(gd))
    adj.save_adjroe_corrs_toh5file(gd.df, corrs, data_file)


@analyze.command()
@click.option('--data-file', default=DEFAULT_GOLD_FILE,
              help='data file for gold level data')
def corrs(data_file):
    do_corrs(data_file)

def do_corrs(data_file):
    gd = adj.load_adjstaging_from_h5file(data_file)
    adj.calc_adj_roes(gd)
    corrs = pd.Series(adj.gen_corr(gd))
    print(corrs)
    print(f"因子显著性, corr mean: {corrs.mean()}")
    print(f"因子稳定性, corr std: {corrs.std()}")
    print(f"因子有效性, IC_IR: {corrs.mean()/corrs.std()}")
    cnt_gt_zero = corrs[corrs > 0].count()
    print(f"因子当中大于零的数目是：{cnt_gt_zero}")
    print(f"因子作用方向稳定性，{cnt_gt_zero/corrs.count()}")

@analyze.command()
@click.option('--gold-file', default=DEFAULT_GOLD_FILE,
              help='data file for gold level data')
def gen_portfolio_data(gold_file):
    do_gen_portfolio_data(gold_file)

def do_gen_portfolio_data(data_file=DEFAULT_GOLD_FILE):
    import qiadj as adj
    import portfolio as ptf
    gd = adj.load_adjstaging_from_h5file(data_file)
    adj.calc_adj_roes(gd)
    adj.gen_corr(gd)
    df = ptf.create_portfolios(gd)
    ptf.save_portfolios(df, data_file)
    return df

cli = click.CommandCollection(sources=[prepdata, analyze])

if __name__ == '__main__':
    cli()
